package com.hdphone.zljutils.impl;

import android.text.TextUtils;

import com.hdphone.zljutils.inter.INumberUtil;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.regex.Pattern;

/**
 * @author sq
 * @date 2020/10/19
 * @describe
 */
public class NumberUtilImpl implements INumberUtil {

    private static final int DEF_DIV_SCALE = 10;

    @Override
    public int string2Int(String s) {
        try {
            return Integer.parseInt(s);
        } catch (Exception e) {
            return 0;
        }
    }

    @Override
    public double getDouble(String s) {
        double value = 0.0;
        try {
            BigDecimal b = new BigDecimal(s);
            value = b.doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    @Override
    public double add(double v1, double v2) {
        double value = 0.0;
        try {
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            value = b1.add(b2).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    @Override
    public double add(String v1, String v2) {
        double value = 0.0;
        try {
            BigDecimal b1 = new BigDecimal(v1);
            BigDecimal b2 = new BigDecimal(v2);
            value = b1.add(b2).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    @Override
    public double substract(double v1, double v2) {
        double value = 0.0;
        try {
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            value = b1.subtract(b2).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    @Override
    public double substract(String v1, String v2) {
        double value = 0.0;
        try {
            BigDecimal b1 = new BigDecimal(v1);
            BigDecimal b2 = new BigDecimal(v2);
            value = b1.subtract(b2).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    @Override
    public double multiply(double v1, double v2) {
        double value = 0.0;
        try {
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            value = b1.multiply(b2).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    @Override
    public double multiply(String v1, String v2) {
        double value = 0.0;
        try {
            BigDecimal b1 = new BigDecimal(v1);
            BigDecimal b2 = new BigDecimal(v2);
            value = b1.multiply(b2).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    @Override
    public double divide(double v1, double v2) {
        return divide(v1, v2, DEF_DIV_SCALE);
    }

    @Override
    public double divide(double v1, double v2, int scale) {
        double value = 0.0;
        try {
            if (scale < 0) {
                return value;
                //throw new IllegalArgumentException("The scale must be a positive integer or zero");
            }
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            value = b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    @Override
    public double round(double v, int scale) {
        double value = 0.0;
        try {
            if (scale < 0) {
                return value;
                // throw new IllegalArgumentException("The scale must be a positive integer or zero");
            }

            BigDecimal b = new BigDecimal(Double.toString(v));
            BigDecimal one = new BigDecimal("1");
            value = b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    @Override
    public double round(double v) {
        try {
            return round(v, 2);
        } catch (Exception e) {
            return v;
        }
    }

    @Override
    public double searchNearValue(double key, Double[] arr) {
        //        double[] arr = {1.78, 2.0, 2.08, 2.17}; 1920*1080;2160*1080;2250*1080;2340*1080
        //        double key = 1.82;
        int search = Arrays.binarySearch(arr, key);
        double searchKey = 0.0;
        int index = 0;
        if (search > 0 && search < arr.length) {
            searchKey = arr[search];
            index = search;
        } else if (search == -1) {
            searchKey = arr[0];
            index = 0;
        } else if (search == -(arr.length + 1)) {
            searchKey = arr[arr.length - 1];
            index = arr.length - 1;
        } else if (search < 0 && search >= -arr.length) {
            index = (-2 + Math.abs(search)) > 0 ? (-2 + Math.abs(search)) : 0;
            searchKey = arr[index];
        } else {
            searchKey = arr[0];
            index = 0;
        }
        double needValue = 0.0;
        int nearIndex = 0;
        if (index == arr.length - 1) {
            needValue = arr[arr.length - 1];
            nearIndex = arr.length - 1;
        } else {
            double min = arr[index];
            double max = arr[index + 1];
            if ((key - min) > (max - key)) {
                needValue = max;
                nearIndex = index + 1;
            } else {
                needValue = min;
                nearIndex = index;
            }
        }
        return needValue;
    }

    @Override
    public String reserve2Decimals(double d) {
        DecimalFormat format = new DecimalFormat("0.00");
        return format.format(d);
    }

    @Override
    public boolean isNumeric(String str) {
        if (TextUtils.isEmpty(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }
}
